package org.huangrui.javase.thread;

import java.util.concurrent.TimeUnit;

/**
 * @Author hr
 * @Create 2025-11-08 15:35
 **/
public class T05ProductorAndConsumer1 {
    public static void main(String[] args) {
        // 1、创建资源类对象
        Workbench1 workbench = new Workbench1();

        class Cook implements Runnable {
            @Override
            public void run() {
                while (true) {
                    workbench.make();
                }
            }
        }
        class Waiter implements Runnable{
            @Override
            public void run() {
                while (true) {
                    workbench.eat();
                }
            }
        }

        // 2、创建和启动厨师线程
        Cook cook = new Cook();
        Thread t1 = new Thread( cook,"厨师1号");
        Thread t2 = new Thread( cook,"厨师2号");
        t1.start();
        t2.start();

        // 3、创建和启动服务员线程
        Waiter waiter = new Waiter();
        Thread t3 = new Thread( waiter,"服务员1号");
        Thread t4 = new Thread( waiter,"服务员3号");
        t3.start();
        t4.start();
    }

}

// 1、定义资源类
class Workbench1 {
    private static final int MAX_VALUE = 2;
    private int total;

    public synchronized void make() {
        // 为了避免虚假唤醒，应该总是使用在循环中。
        while (total >= MAX_VALUE) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 暂停毫秒
        try { TimeUnit.MILLISECONDS.sleep(50); } catch (InterruptedException e) { throw new RuntimeException(e); }

        total++;
        System.out.println(Thread.currentThread().getName() + "制作了一份快餐，现在工作台上有：" + total + "份快餐");
        this.notifyAll();
    }

    public synchronized void eat() {
        // 为了避免虚假唤醒，应该总是使用在循环中。
        while (total <= 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try { TimeUnit.MILLISECONDS.sleep(50); } catch (InterruptedException e) { throw new RuntimeException(e); }
        total--;
        System.out.println(Thread.currentThread().getName() + "取走了一份快餐，现在工作台上有：" + total + "份快餐");
        this.notifyAll();
    }
}